package zk_task

import (
	"EasyReson/global"
	"github.com/samuel/go-zookeeper/zk"
	"time"
	"fmt"
	"EasyReson/monitor"
	"EasyReson/util"
)

const (
	rootNode= "/easyreson" //根节点
	goroutine="goroutine"//协程数
	memory="memory"//内存
	taskId="taskId"//任务id
	taskName="taskName"//任务名称
	taskCommond="taskCommond"//任务注释
	cron="cron"//定时任务表达式
	thread="thread"//任务启用线程数
	db1srcIp="db1-src-ip"//db1src数据库连接ip
	db1srcPort="db1-src-port"//db1src数据库连接端口
	db1srcDatabase="db1-src-database"//db1src数据库连接数据库
	db1srcTable="db1-src-table"//db1src 任务表名
	db1srcKey="db1-src-key"//db1src 任务表名 主键
	db2srcIp="db2-src-ip"//db1src数据库连接ip
	db2srcPort="db2-src-port"//db1src数据库连接端口
	db2srcDatabase="db2-src-database"//db1src数据库连接数据库
	db2srcTable="db2-src-table"//db1src 任务表名
	db2srcKey="db2-src-key"//db1src 任务表名 主键
	dbdestIp="dbdest-ip"//dbdest数据库连接ip
	dbdestPort="ddest-port"//dbdest数据库连接端口
	dbdestDatabase="dbdest-database"//dbdest数据库连接数据库
	dbdestTable="dbdest-table"//dbdest 任务表名

	open="open"//一个开关，用户从zk上手动触发修改为任意值后，手动触发定时任务
	stop="stop"//用于对正在执行的定时任务进行暂停和启动

)

/**
	开始配置每一个任务的具体配置项目，并注册监听
 */
func createChildSessionNodeIfExists(task *global.Task) {

    go createIfNotExists(task)

	//针对某些热配置有意义的属性，进行了监听和回调
	/**
		手动触发定时任务
	 */
	WatcherOpen :=&taskWatcherAndNotify{make(chan (<-chan zk.Event)),task,getTaskConfigNode(task.TaskName,open)}
	WatcherOpen.StartWatchAndNotify()
	/**
		暂停定时任务
	 */
	WatcherStop :=&taskWatcherAndNotify{make(chan (<-chan zk.Event)),task,getTaskConfigNode(task.TaskName,stop)}
	WatcherStop.StartWatchAndNotify()

}
/**
	如果配置节点不存在，就创建
	采用心跳检测的方式,原因：程序重启期间，zk会删除临时节点，因此，只创建一次节点可能会失效
 */
func createIfNotExists(task *global.Task) {
	for {

		createSessionNodeIfExists(getTaskConfigNode(task.TaskName,taskId),util.ToString(task.TaskId))
		createSessionNodeIfExists(getTaskConfigNode(task.TaskName,taskName),util.ToString(task.TaskName))
		createSessionNodeIfExists(getTaskConfigNode(task.TaskName,taskCommond),util.ToString(task.TaskCommond))
		createSessionNodeIfExists(getTaskConfigNode(task.TaskName,cron),util.ToString(task.Cron))
		createSessionNodeIfExists(getTaskConfigNode(task.TaskName,thread),util.ToString(task.Thread))

		createSessionNodeIfExists(getTaskConfigNode(task.TaskName,db1srcIp),util.ToString(task.Db1Src.Ip))
		createSessionNodeIfExists(getTaskConfigNode(task.TaskName,db1srcPort),util.ToString(task.Db1Src.Port))
		createSessionNodeIfExists(getTaskConfigNode(task.TaskName,db1srcDatabase),util.ToString(task.Db1Src.Database))
		createSessionNodeIfExists(getTaskConfigNode(task.TaskName,db1srcTable),util.ToString(task.Db1Src.Table))
		createSessionNodeIfExists(getTaskConfigNode(task.TaskName,db1srcKey),util.ToString(task.Db1Src.Key))

		createSessionNodeIfExists(getTaskConfigNode(task.TaskName,db2srcIp),util.ToString(task.Db2Src.Ip))
		createSessionNodeIfExists(getTaskConfigNode(task.TaskName,db2srcPort),util.ToString(task.Db2Src.Port))
		createSessionNodeIfExists(getTaskConfigNode(task.TaskName,db2srcDatabase),util.ToString(task.Db2Src.Database))
		createSessionNodeIfExists(getTaskConfigNode(task.TaskName,db2srcTable),util.ToString(task.Db2Src.Table))
		createSessionNodeIfExists(getTaskConfigNode(task.TaskName,db2srcKey),util.ToString(task.Db2Src.Key))

		createSessionNodeIfExists(getTaskConfigNode(task.TaskName,dbdestIp),util.ToString(task.DBDest.Ip))
		createSessionNodeIfExists(getTaskConfigNode(task.TaskName,dbdestPort),util.ToString(task.DBDest.Port))
		createSessionNodeIfExists(getTaskConfigNode(task.TaskName,dbdestDatabase),util.ToString(task.DBDest.Database))
		createSessionNodeIfExists(getTaskConfigNode(task.TaskName,dbdestTable),util.ToString(task.DBDest.Table))

		createSessionNodeIfExists(getTaskConfigNode(task.TaskName,open),"123456")
		createSessionNodeIfExists(getTaskConfigNode(task.TaskName,stop),"false")

		time.Sleep(30*time.Second)
	}
}
/**
	在应用的namespace下创建协程数量和内存利用率的信息
 */
func createIfNoExistsMemAndGetGoroutine() {
	for{
		createSetSessionNode(getTaskNode(goroutine),fmt.Sprintf("%v",monitor.GetGoroutine()))
		v1,v2,v3,v4:= monitor.GetMemoryMb()
		createSetSessionNode(getTaskNode(memory),fmt.Sprintf("%s,%s,%s,%s",v1,v2,v3,v4))

		time.Sleep(10*time.Second)
	}
}
